package com.example.administrator.drinkdevice;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.os.Environment;
import android.os.Message;
import android.os.Process;
import android.support.v4.view.ViewPager;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;

import com.example.administrator.drinkdevice.databinding.ActivityMainBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelCheckdeviceBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelCheckupdateBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelGoodssettingBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelLoginBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelPaysuccessBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelPicktestBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelSaletodaysumBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelSelectgoodsBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelServersetBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelSettingBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelSettlementBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelTestselectgoodsBinding;
import com.example.administrator.drinkdevice.databinding.ViewmodelUpdateadminpwdBinding;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipOutputStream;

import BaseActivity.*;
import Component.CustomViewPager;
import Component.ViewPagerAdapter;
import Const.PublicDefine;
import Device.cola.ColaReader;
import Device.printer.printer_control;
import Device.scanner_mp86.mp86_Constant;
import Device.scanner_mp86.mp86_control;
import Enums.NetworkType_Enum;
import Helper.MQTT;
import Interface.*;
import Service.SysService;
import ViewModel.CheckDevice_ViewModel;
import ViewModel.CheckUpdate_ViewModel;
import ViewModel.GoodsSetting_ViewModel;
import ViewModel.Login_ViewModel;
import ViewModel.MainActivity_ViewModel;
import ViewModel.PaySuccess_ViewModel;
import ViewModel.PickTest_ViewModel;
import ViewModel.SaleTodaySum_ViewModel;
import ViewModel.SelectGoods_ViewModel;
import ViewModel.ServerSet_ViewModel;
import ViewModel.Setting_ViewModel;
import ViewModel.Settlement_ViewModel;
import ViewModel.TestSelectGoods_ViewModel;
import ViewModel.UpdateAdminPwd_ViewModel;

public class MainActivity extends BaseActivity implements INetworkStateChange {

    private MainActivity_ViewModel viewModel;
    private ViewPagerAdapter adapter;
    private CustomViewPager viewPager;
    private SelectGoods_ViewModel selectGoodsViewModel;
    private Setting_ViewModel settingViewModel;
    private ServerSet_ViewModel serverSetViewModel;
    private Login_ViewModel login_viewModel;
    private GoodsSetting_ViewModel goodsSettingViewModel;
    private PickTest_ViewModel pickTestViewModel;
    private SaleTodaySum_ViewModel saleTodaySumViewModel;
    private UpdateAdminPwd_ViewModel updateAdminPwdViewModel;
    private CheckDevice_ViewModel checkDeviceViewModel;
    private CheckUpdate_ViewModel checkUpdateViewModel;
    private TestSelectGoods_ViewModel testSelectGoodsViewModel;
    private Settlement_ViewModel settlementViewModel;
    private PaySuccess_ViewModel paySuccessViewModel;

    private MQTT mqtt = null;
    private List<View> list_view = new ArrayList<View>();
    private int pageIndex = 0;
    private boolean initFlag = false;
    private boolean exitFlag = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            viewModel = new MainActivity_ViewModel(this);
            ActivityMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            dataBinding.setViewModel(viewModel);

            String DeviceName = String.format("%s_%08X_%08X", PublicDefine.cinemaInfo.getString("cinemaCode"), SysService.DeviceType, SysService.DeviceID);
            mqtt = new MQTT(MainActivity.this, DeviceName, MQTTRecvMsg);

            //初始化饮料机
            initDevice();

            //初始化页面
            viewPager = findViewById(R.id.viewPager);
            initGuideView();
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    private IAsynCallBackListener MQTTRecvMsg = new IAsynCallBackListener() {
        @Override
        public void onFinish(Object sender, Object data) {
            try {
                JSONObject resjson = new JSONObject();
                resjson.put("return_code", 1);
                resjson.put("return_msg", "");
                String topic = sender.toString();
                String[] cmdList = topic.split("/");
                JSONObject recvdata = new JSONObject(data.toString());
                switch (cmdList[cmdList.length - 1]) {
                    case "getfilelist": {
                        resjson.put("return_code", 0);
                        String packageName = recvdata.get("dir").toString();
                        String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + packageName;
                        File Logfile = new File(filePath);
                        File[] flist = Logfile.listFiles();
                        if (flist == null) {
                            return;
                        }
                        resjson.put("list", new JSONArray());
                        int i = 0;
                        for (File f : flist) {
                            JSONObject jf = new JSONObject();
                            jf.put("isDirectory", f.isDirectory());
                            jf.put("name", f.getName());
                            jf.put("size", f.length());
                            jf.put("updateTime", new SimpleDateFormat("yyyy-MM-dd").format(new Date(f.lastModified())));
                            resjson.getJSONArray("list").put(i, jf);
                            i++;
                        }
                        mqtt.SendData(resjson, topic);
                        break;
                    }
                    case "downfile": {
                        resjson.put("return_code", 0);
                        String packageName = recvdata.get("file").toString();
                        String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + packageName;
                        File f = new File(filePath);
                        String fname = f.getName().substring(0, f.getName().lastIndexOf(".") - 1);
                        ZipOutputStream zipfile = new ZipOutputStream(new FileOutputStream(f.getParent() + "/" + fname + ".zip"));
                        Helper.EnjoyTools.ZipFiles(f.getParent() + "/", f.getName(), zipfile);
                        zipfile.close();
                        File Logfile = new File(f.getParent() + "/" + fname + ".zip");
                        RandomAccessFile raf = new RandomAccessFile(Logfile, "rwd");
                        byte[] fileData = new byte[(int) raf.length()];
                        raf.read(fileData);
                        raf.close();
                        mqtt.SendData(topic, fileData);
                        Logfile.delete();
                        break;
                    }
                    case "deletefile": {
                        resjson.put("return_code", 0);
                        String packageName = recvdata.get("file").toString();
                        String filePath = Environment.getExternalStorageDirectory().getPath() + "/" + packageName;
                        File Logfile = new File(filePath);
                        if (Logfile.isDirectory()) {
                            DeleteDir(filePath);
                        } else {
                            Logfile.delete();
                        }
                        mqtt.SendData(resjson, topic);
                        break;
                    }
                    default: {
                        mqtt.SendData(resjson, topic);
                        break;
                    }
                }

            } catch (Exception e) {
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("return_code", -1);
                    jsonObject.put("return_msg", e.getMessage());
                    mqtt.SendData(jsonObject, sender.toString());
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        }

        @Override
        public void onError(Object sender, Exception e) {

        }
    };

    private void DeleteDir(String dirName) {
        File df = new File(dirName);
        if (df == null) {
            return;
        }
        File[] flist = df.listFiles();
        for (File f : flist) {
            if (f.isDirectory()) {
                File[] childFile = f.listFiles();
                if (childFile == null || childFile.length == 0) {
                    f.delete();
                    continue;
                }
                for (File sf : childFile) {
                    if (sf.isDirectory()) {
                        DeleteDir(sf.getAbsolutePath());
                    } else {
                        sf.delete();
                    }
                }
                f.delete();
            } else {
                f.delete();
            }
        }
        df.delete();
    }

    private void initGuideView() {
        LayoutInflater inflater = LayoutInflater.from(this);
        //选卖品
        selectGoodsViewModel = new SelectGoods_ViewModel(this, viewPager, viewModel);
        final ViewmodelSelectgoodsBinding selectgoodsBinding = ViewmodelSelectgoodsBinding.inflate(inflater);
        selectgoodsBinding.setViewModel(selectGoodsViewModel);
        list_view.add(selectgoodsBinding.getRoot());
        //登录
        login_viewModel = new Login_ViewModel(this, viewPager, viewModel);
        ViewmodelLoginBinding loginBinding = ViewmodelLoginBinding.inflate(inflater);
        loginBinding.setViewModel(login_viewModel);
        list_view.add(loginBinding.getRoot());
        //设置
        settingViewModel = new Setting_ViewModel(this, viewPager, viewModel);
        ViewmodelSettingBinding settingBinding = ViewmodelSettingBinding.inflate(inflater);
        settingBinding.setViewModel(settingViewModel);
        list_view.add(settingBinding.getRoot());
        //服务器设置
        serverSetViewModel = new ServerSet_ViewModel(this, viewPager, viewModel);
        ViewmodelServersetBinding serversetBinding = ViewmodelServersetBinding.inflate(inflater);
        serversetBinding.setViewModel(serverSetViewModel);
        list_view.add(serversetBinding.getRoot());
        //卖品设置
        goodsSettingViewModel = new GoodsSetting_ViewModel(this, viewPager, viewModel);
        ViewmodelGoodssettingBinding goodssettingBinding = ViewmodelGoodssettingBinding.inflate(inflater);
        goodssettingBinding.setViewModel(goodsSettingViewModel);
        list_view.add(goodssettingBinding.getRoot());
        //接杯测试
        pickTestViewModel = new PickTest_ViewModel(this, viewPager, viewModel);
        ViewmodelPicktestBinding picktestBinding = ViewmodelPicktestBinding.inflate(inflater);
        picktestBinding.setViewModel(pickTestViewModel);
        list_view.add(picktestBinding.getRoot());
        //当天售卖汇总
        saleTodaySumViewModel = new SaleTodaySum_ViewModel(this, viewPager, viewModel);
        ViewmodelSaletodaysumBinding saletodaysumBinding = ViewmodelSaletodaysumBinding.inflate(inflater);
        saletodaysumBinding.setViewModel(saleTodaySumViewModel);
        list_view.add(saletodaysumBinding.getRoot());
        //修改管理员密码
        updateAdminPwdViewModel = new UpdateAdminPwd_ViewModel(this, viewPager, viewModel);
        ViewmodelUpdateadminpwdBinding updateadminpwdBinding = ViewmodelUpdateadminpwdBinding.inflate(inflater);
        updateadminpwdBinding.setViewModel(updateAdminPwdViewModel);
        list_view.add(updateadminpwdBinding.getRoot());
        //外设检测
        checkDeviceViewModel = new CheckDevice_ViewModel(this, viewPager, viewModel);
        ViewmodelCheckdeviceBinding checkdeviceBinding = ViewmodelCheckdeviceBinding.inflate(inflater);
        checkdeviceBinding.setViewModel(checkDeviceViewModel);
        list_view.add(checkdeviceBinding.getRoot());
        //检查更新
        checkUpdateViewModel = new CheckUpdate_ViewModel(this, viewPager, viewModel);
        ViewmodelCheckupdateBinding checkupdateBinding = ViewmodelCheckupdateBinding.inflate(inflater);
        checkupdateBinding.setViewModel(checkUpdateViewModel);
        list_view.add(checkupdateBinding.getRoot());
        //测试主页
        testSelectGoodsViewModel = new TestSelectGoods_ViewModel(this, viewPager, viewModel);
        ViewmodelTestselectgoodsBinding testselectgoodsBinding = ViewmodelTestselectgoodsBinding.inflate(inflater);
        testselectgoodsBinding.setViewModel(testSelectGoodsViewModel);
        list_view.add(testselectgoodsBinding.getRoot());
        //结算
        settlementViewModel = new Settlement_ViewModel(this, viewPager, viewModel);
        ViewmodelSettlementBinding settlementBinding = ViewmodelSettlementBinding.inflate(inflater);
        settlementBinding.setViewModel(settlementViewModel);
        list_view.add(settlementBinding.getRoot());
        //支付完成
        paySuccessViewModel = new PaySuccess_ViewModel(this, viewPager, viewModel);
        ViewmodelPaysuccessBinding paysuccessBinding = ViewmodelPaysuccessBinding.inflate(inflater);
        paysuccessBinding.setViewModel(paySuccessViewModel);
        list_view.add(paysuccessBinding.getRoot());

        adapter = new ViewPagerAdapter(list_view);
        viewPager.setAdapter(adapter);
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (!initFlag && position == 0) {
                    //执行第一个页面的初始化
                    initFlag = true;
                    selectGoodsViewModel.Init();
                }
            }

            @Override
            public void onPageSelected(int position) {
                try {
                    View focusView = MainActivity.this.getCurrentFocus();
                    clearFocus(focusView);

                    pageIndex = position;
                    if (pageIndex != 0) {
                        selectGoodsViewModel.exitflag = true;
                    }
                    switch (position) {
                        case 0:
                            selectGoodsViewModel.Init();
                            break;
                        case 1:
                            login_viewModel.Init();
                            break;
                        case 2:
                            settingViewModel.Init();
                            break;
                        case 3:
                            serverSetViewModel.Init();
                            break;
                        case 4:
                            goodsSettingViewModel.Init();
                            break;
                        case 5:
                            pickTestViewModel.Init();
                            break;
                        case 6:
                            saleTodaySumViewModel.Init();
                            break;
                        case 7:
                            updateAdminPwdViewModel.Init();
                            break;
                        case 8:
                            checkDeviceViewModel.Init();
                            break;
                        case 9:
                            checkUpdateViewModel.Init();
                            break;
                        case 10:
                            testSelectGoodsViewModel.Init();
                            break;
                        case 11:
                            settlementViewModel.Init();
                            break;
                        case 12:
                            paySuccessViewModel.Init();
                            break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                System.out.print(state);
            }
        });

    }

    @Override
    public void NetworkStateEvent(NetworkType_Enum NetworkType, boolean ConnState) {

    }

    public void initDevice() {
        try {
            //打开串口
            PublicDefine.colaReader = new ColaReader();
            PublicDefine.colaReader.SetIntent(MainActivity.this, getIntent());
        } catch (Exception e) {
            e.printStackTrace();
            alert(GetExceptionMsg(e));
        }

        try {
            PublicDefine.printerControl = new printer_control();
            //打开串口
            if (!PublicDefine.printerControl.isOpen) {
                int ret = PublicDefine.printerControl.openSerialPort();
                if (ret < 0) {
                    throw new Exception("打开打印设备串口失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            alert(GetExceptionMsg(e));
        }

        try {
            PublicDefine.mp86Control = new mp86_control();
            if (!PublicDefine.mp86Control.isOpen) {
                int ret = PublicDefine.mp86Control.openSerialPort();
                if (ret < 0) {
                    throw new Exception("打开mp86设备串口失败");
                }

                //设置扫码成功后蜂鸣器状态
                ret = PublicDefine.mp86Control.Check_Device_Is_OK();
                if (ret != 0) {
                    throw new Exception("扫码设备不正常，异常码:" + ret);
                }
                //设置都可以扫什么码
                ret = PublicDefine.mp86Control.Set_QR_DM_Barcode_NFC_Function(true, false, false, true);
                if (ret != 0) {
                    throw new Exception("设置扫描器QR、条码、NFC工作参数失败:" + ret);
                }
                //设置扫码工作模式,每4秒会上报一次
                ret = PublicDefine.mp86Control.Set_Scan_Work_Mode(mp86_Constant.SCAN_WORK_MODE_INTERVAL, 4);
                if (ret != 0) {
                    throw new Exception("设置扫描器扫码工作模式失败:" + ret);
                }
                //设置扫码成功后LED状态,显示绿灯
                ret = PublicDefine.mp86Control.Set_Scan_Success_LED_Status(mp86_Constant.SCAN_SUCCESS_LED_GREEN);
                if (ret != 0) {
                    throw new Exception("设置扫码成功后LED状态:失败:" + ret);
                }

                //设置LED和蜂器状态
                ret = PublicDefine.mp86Control.Set_LED_And_Beep_Control(mp86_Constant.LED_AND_BEEP_CONTROL_RED_LED, 3, 300, 400);
                if (ret != 0) {
                    throw new Exception("扫码器控制红灯:失败:" + ret);
                }
                //进入命令模式
                ret = PublicDefine.mp86Control.Open_Command_Mode(true);
                if (ret != 0) {
                    throw new Exception("打开命令模式失败:" + ret);
                }
                //结果上报模式为命令查询
                ret = PublicDefine.mp86Control.Scanner_Result_Notify_Mode(mp86_Constant.SCANNER_RESULT_CMD_LOOP);
                if (ret != 0) {
                    throw new Exception("扫描器设置上报模式失败:" + ret);
                }

                exitFlag = false;
                Thread thread = new Thread(CheckCardThread);
                thread.start();
            }

        } catch (Exception e) {
            e.printStackTrace();
            alert(GetExceptionMsg(e));
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent me) {
        if (me.getAction() == MotionEvent.ACTION_DOWN) {  //把操作放在用户点击的时候
            View focusView = MainActivity.this.getCurrentFocus();
            if (focusView != null) {
                if (isShouldHideKeyboard(focusView, me)) { //判断用户点击的是否是输入框以外的区域
                    focusView.clearFocus();
                    InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                    mInputMethodManager.hideSoftInputFromWindow(focusView.getWindowToken(), 0);
                }
            }
        }
        return super.dispatchTouchEvent(me);
    }

    private boolean isShouldHideKeyboard(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {  //判断得到的焦点控件是否包含EditText
            int[] l = {0, 0};
            v.getLocationInWindow(l);
            int left = l[0],    //得到输入框在屏幕中上下左右的位置
                    top = l[1],
                    bottom = top + v.getHeight(),
                    right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 点击位置如果是EditText的区域，忽略它，不收起键盘。
                return false;
            } else {
                return true;
            }
        }
        // 如果焦点不是EditText则忽略
        return false;
    }

    private Runnable CheckCardThread = new Runnable() {
        @Override
        public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            Object obj = new Object();
            boolean isClose = false;
            while (!exitFlag) {
                try {
                    if (pageIndex != 11) {
                        isClose = false;
                    }
                    if (pageIndex == 11) {
                        if (!isClose) {
                            //页面开启清除旧扫描信息
                            PublicDefine.mp86Control.Set_Scan_Success_Beep_Status(mp86_Constant.SCAN_SUCCESS_BEEP_OFF);
                            byte[] scan_result_info = new byte[256];
                            PublicDefine.mp86Control.Scanner_Get_Result(scan_result_info);
                            PublicDefine.mp86Control.Set_Scan_Success_Beep_Status(mp86_Constant.SCAN_SUCCESS_BEEP_ON);
                            isClose = true;
                        }

                        //获取扫描结果
                        byte[] scan_result_info = new byte[256];
                        final int ret = PublicDefine.mp86Control.Scanner_Get_Result(scan_result_info);
                        if (ret == mp86_Constant.SCANNER_RESPONSE_RESULT_QR || ret == mp86_Constant.SCANNER_RESPONSE_RESULT_CARD) {
                            final String resultS = new String(scan_result_info).trim();
                            Message msg = new Message();
                            msg.obj = new IAsynCallBackListener() {
                                @Override
                                public void onFinish(Object sender, Object data) {
                                    if (ret == mp86_Constant.SCANNER_RESPONSE_RESULT_QR) {
                                        settlementViewModel.scan(resultS);
                                    }
                                    if (ret == mp86_Constant.SCANNER_RESPONSE_RESULT_CARD) {
                                        settlementViewModel.brushCard(resultS);
                                    }
                                }

                                @Override
                                public void onError(Object sender, Exception e) {

                                }
                            };
                            mHandler.sendMessage(msg);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (obj) {
                    try {
                        obj.wait(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int keyCode = event.getKeyCode();

        if (event.isCtrlPressed() && event.isAltPressed() && keyCode == KeyEvent.KEYCODE_A
                && event.getAction() == KeyEvent.ACTION_DOWN && pageIndex == 0) {
            viewPager.setCurrentItem(1);
            return false;
        } else {
            super.dispatchKeyEvent(event);
            return true;
        }
    }
}